import { create } from 'zustand'

type State = {
    // 左侧栏
    leftTabActiveKey: string;
    // 右侧栏
    rightTabActiveKey: string;
    // 底部栏
    bottomActiveKey: string;
    // 文件管理器
    fileTree: any[];
    filteredTree: any[];
    projectPath: string;
    // 编辑视图
    viewType: string;
    viewItems: any[];
    viewActiveKey: string;
    // 任务控制
    taskStatus: string;
    isStep: boolean;
    breakpoints: Map<string, Set<string>>;// 打的断点
    executionResult: Map<string, {
        dones: Set<number>, // 成功的
        errors: Set<number>, // 失败的
        warnings: Set<number> // 报警的
    }>;// 执行结果

    actions: {
        updateLeftTabActiveKey: (activeKey: string) => void;
        updateRightTabActiveKey: (activeKey: string) => void;
        updateBottomTabActiveKey: (activeKey: string) => void;
        changeViewType: (type: string) => void;
        setFileTree: (fileTree: any) => void;
        setViewActiveKey: (activeKey: string) => void;
        removeViewItem: (activeKey: string) => void;
        addViewItem: () => void;
        moveViewCommand: (dragIndex: number, hoverIndex: number, commandData: any) => void;
        setTaskStatus: (taskStatus: string) => void;
        taskStart: (isStep: boolean) => Promise<any>;
        taskPause: () => Promise<any>;
        taskResume: () => Promise<any>;
        taskStop: () => Promise<any>;
        addDones: (task: string, index: number) => void;
        selectFileAsync: (selectedFile: any) => void;
        setProjectPath: (path: string) => void;
        setFilteredTree: (filteredTree: any) => void;
    }
}

export const useAppStore = create<State>((set, get) => ({
    breakpoints: new Map(),
    executionResult: new Map(),
    // 左侧栏
    leftTabActiveKey: 'file_explorer',
    // 右侧栏
    rightTabActiveKey: '',
    // 底部栏
    bottomActiveKey: '',
    // 编辑视图
    viewType: 'list', // 视图类型 list列表视图 source 源码视图
    viewItems: [], // 视图tabItems，编辑后缓存下来，点击保存才保存到本地硬盘
    viewActiveKey: '', // 当前视图
    // 项目根目录
    projectPath: '',
    // 文件树
    fileTree: [],
    // 打开中的文件列表
    // 搜索到的树
    filteredTree: [],
    // 任务开始执行
    isStep: false,
    taskStatus: 'IDLE',
    actions: {
        updateLeftTabActiveKey: (leftTabActiveKey) => {
            set({ leftTabActiveKey })
        },
        updateRightTabActiveKey: (rightTabActiveKey) => {
            set({ rightTabActiveKey })
        },
        // 切换视图模式
        changeViewType: (viewType: string) => {
            set({ viewType });
        },
        updateBottomTabActiveKey: (bottomActiveKey) => {
            set({ bottomActiveKey })
        },
        // 移除视图
        removeViewItem: (targetKey: string) => {
            const { viewItems, viewActiveKey } = get()
            const targetIndex = viewItems.findIndex(item => item.id === targetKey);
            const lastIndex = targetIndex - 1;
            let newActiveKey = viewActiveKey;
            const newPanes = viewItems.filter((item) => item.id !== targetKey);
            if (newPanes.length && newActiveKey === targetKey) {
                if (lastIndex >= 0) {
                    newActiveKey = newPanes[lastIndex].id;
                } else {
                    newActiveKey = newPanes[0].id;
                }
            }
            set({
                viewItems: newPanes,
                viewActiveKey: newActiveKey
            })
        },
        // 增加视图
        addViewItem: () => {
            const newActiveKey = `${Math.random()}`;
            set((state) => {
                return {
                    viewItems: [...state.viewItems, {
                        id: newActiveKey,
                        name: 'UnTitled',
                        source: '',
                        commands: []
                    }],
                    viewActiveKey: newActiveKey
                }
            })
        },
        // 移动视图中的命令
        moveViewCommand: (dragIndex: number, hoverIndex: number, commandData: any) => {
            const { viewItems, viewActiveKey } = get();
            const newViewItems = [...viewItems]
            const index = viewItems.findIndex(item => item.id === viewActiveKey);
            const commands = viewItems[index].commands;
            const newCommands = [...commands];
            if (dragIndex > -1) {
                newCommands.splice(dragIndex, 1)
            }
            newCommands.splice(hoverIndex, 0, commandData);
            newViewItems[index] = {
                ...newViewItems[index],
                commands: newCommands
            }
            set({
                viewItems: newViewItems
            })
        },
        addDones: (task: string, index: number) => {
            const executionResult = get().executionResult;
            const newExecutionResult = new Map(executionResult)
            const taskExecutionResult = newExecutionResult.get(task)
            if (taskExecutionResult) {
                const newObj = {
                    ...taskExecutionResult,
                    dones: taskExecutionResult.dones.add(index)
                }
                newExecutionResult.set(task, newObj)
            } else {
                const obj = {
                    dones: new Set<number>(),
                    warnings: new Set<number>(),
                    errors: new Set<number>(),
                }
                obj.dones.add(index)
                newExecutionResult.set(task, obj)
            }
            set({
                executionResult: newExecutionResult
            })
        },
        // 任务开始执行
        taskStart: async (isStep: boolean = false) => {
            const { projectPath, viewActiveKey, viewItems } = get();
            const viewItem = viewItems.find(item => item.id === viewActiveKey);
            const taskName = viewItem.name;
            set({
                isStep
            })
            await window.electron?.ipcRenderer.invoke('task:start', taskName, {
                isStep,
                isPlayFromHere: false,
                breakpoints: [],
                projectPath
            })
        },
        // 任务暂停执行
        taskPause: async () => {
            await window.electron?.ipcRenderer.invoke('task:pause')
        },
        // 任务恢复执行
        taskResume: async () => {
            await window.electron?.ipcRenderer.invoke('task:resume')
        },
        // 任务停止执行
        taskStop: async () => {
            await window.electron?.ipcRenderer.invoke('task:stop')
        },
        // 设置任务状态
        setTaskStatus: (taskStatus: string) => {
            set({
                taskStatus
            })
        },

        setFileTree: (fileTree: any) => {
            set(({ fileTree }))
        },

        // 选中文件，创建对应的tab
        selectFileAsync: async (selectedFile: any) => {
            const viewItems = get().viewItems;
            set({ viewActiveKey: selectedFile.id })
            if (!viewItems.find(item => item.id === selectedFile.id)) {
                const dataString: string | undefined = await window.electron?.ipcRenderer.invoke('fs:readFile', selectedFile.id);
                if (dataString) {
                    const data = JSON.parse(dataString);
                    selectedFile.source = dataString; // 源码
                    selectedFile.commands = data.Commands.map((item: any) => {
                        return {
                            cmd: item.Command,
                            description: item.Description,
                            target: item.Target,
                            value: item.Value
                        }
                    })
                }

                set((state) => ({
                    viewItems: [...state.viewItems, selectedFile]
                }))
            }
        },
        setViewActiveKey: (viewActiveKey) => {
            set({ viewActiveKey })
        },
        setFilteredTree: (filteredTree: any) => {
            set(() => ({ filteredTree }))
        },
        setProjectPath: (path: string) => {
            set(() => ({ projectPath: path }))
        },


    }

}))

